package utils {
	
	import com.drm.utils.DRMUtils;
	
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.IBitmapDrawable;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLVariables;
	import flash.utils.ByteArray;
	
	import mx.collections.ArrayCollection;
	import mx.controls.Button;
	import mx.controls.CheckBox;
	import mx.controls.ComboBase;
	import mx.controls.ComboBox;
	import mx.controls.DataGrid;
	import mx.controls.DateField;
	import mx.controls.Label;
	import mx.controls.NumericStepper;
	import mx.controls.RadioButton;
	import mx.controls.TextArea;
	import mx.controls.TextInput;
	import mx.controls.listClasses.ListBase;
	import mx.core.Container;
	import mx.core.FlexGlobals;
	import mx.core.UIComponent;
	import mx.graphics.codec.JPEGEncoder;
	import mx.managers.ISystemManager;
	import mx.managers.PopUpManager;
	import mx.utils.StringUtil;

	public final class SMUtils {
		
		private static var acentos:Array = ['á', 'à', 'ã', 'â', 'ä',
			'é', 'è', 'ê', 'ë', 'í', 'ì', 'î', 'ï', 'ó', 'ò', 'õ', 'ô', 'ö',
			'ú', 'ù', 'û', 'ü', 'ñ', 'ý', 'ç', '~', '^', '´', '`', '¨', '@', 
			'#', '$', '%', '&', '*', '§', '\'', '£', '¢', '¬', '°', '¹', '²', '³'];
		
		private static var semAcentos:Array = ['a', 'a', 'a', 'a',
			'a', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'o', 'o', 'o', 'o',
			'o', 'u', 'u', 'u', 'u', 'n', 'y', 'c', ' ', ' ', ' ', ' ', ' ', 
			' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '];
		
		private static function selectListXmlList(list:ListBase, xmlList:XMLList, campo:String = 'codigo') : void {
			
			if (xmlList == null || xmlList.length() == 0) {
				return;
			}
			
			var indices:Array = new Array();			
			for (var j:int = 0; j < xmlList.length(); j++) {
				for (var i:int = 0; i < list.dataProvider.length; i++) {
					if (xmlList[j][campo] == list.dataProvider[i][campo]) {
						indices.push(i);							
						break;
					}
				}
			}
			
			list.selectedIndices = indices;
			
		} 
		
		private static function getAllFieldsByContainer(form:Container, array:Array):Array {
			
			var field:DisplayObject;
			
			var children:Array = form.getChildren();
			
			for (var i:int = 0; i < children.length; i++) {
				
				field = children[i];
				
				if (field is Container) {
					getAllFieldsByContainer(Container(field), array);
				} else if (field is DateField) {
					array.push(field);
				} else if (field is TextInput || field is TextArea || field is NumericStepper
				|| field is ComboBase || field is CheckBox || field is RadioButton || field is ListBase
				|| field is Button) {
					array.push(field);
				} 
			}
			
			return array;
			
		}
		
		public static function selectField(field:UIComponent, value:Object, campo:String = 'codigo') : void {
			
			if (value == null) {
				return;
			}
			
			if (field is DateField) {
				DateField(field).text = String(value);
			} else if (field is TextInput) {
				TextInput(field).text = String(value);
			} else if (field is NumericStepper) {
				NumericStepper(field).value = Number(value);
			} else if (field is TextArea) {
				TextArea(field).text = String(value);
			} else if (field is Label) {
				Label(field).text = String(value);
			} else if (field is ComboBox) {
				selectComboBox(ComboBox(field), String(value), campo);
			} else if (field is ListBase) {
				selectList(ListBase(field), value, campo);
			} else if (field is CheckBox) {
				if (value is Boolean) {
					CheckBox(field).selected = Boolean(value);
				} else if (value.toString() == 'S' || value.toString() == '1' || value.toString() == 'true') {
					CheckBox(field).selected = true;
				} else if (value.toString() == 'N' || value.toString() == '0' || value.toString() == 'false') {
					CheckBox(field).selected = false;
				}
			} 
			
		} 
		
		public static function disableForm(form:Container, opcao:Boolean = false) : void {
			disableFormExcept(form, null);
		}
		
		public static function disableFormExcept(form:Container, except:Array, opcao:Boolean = false) : void {
			
			var children:Array = getAllFieldsByContainer(form, new Array());
			
			var field:DisplayObject;
			
			for (var i:int = 0; i < children.length; i++) {
				
				field = children[i];
				
				var aux:Boolean = true;
				
				if (except != null) {
					
					for (var j:int = 0; j < except.length; j++) {
						if (except[j] == field) {
							aux = false;
							break;
						}
					}
					
				}
				
				if (aux) {
					if (field is DateField) {
						DateField(field).editable = opcao;
					} else if (field is TextInput) {
						TextInput(field).editable = opcao;
					} else if (field is TextArea) {
						TextArea(field).editable = opcao;
					} else if (field is ComboBase) {
						ComboBase(field).enabled = opcao;
					} else if (field is Button) {
						Button(field).enabled = opcao;
					} else if (field is CheckBox) {
						CheckBox(field).enabled = opcao;
					} else if (field is RadioButton) {
						RadioButton(field).enabled = opcao;
					} else if (field is DataGrid) {
						DataGrid(field).allowDragSelection = opcao;
					} else if (field is ListBase) {
						ListBase(field).enabled = opcao;
					} else if (field is NumericStepper) {
						NumericStepper(field).enabled = opcao;
					} 
				}
				
			}
			
		}
		
		public static function clearForm(form:Container) : void {
			clearFormExcept(form, null);
		}
		
		public static function clearFormExcept(form:Container, except:Array) : void {
			
			var children:Array = getAllFieldsByContainer(form, new Array());
			
			var field:DisplayObject;
			
			for (var i:int = 0; i < children.length; i++) {
				
				field = children[i];
				
				var aux:Boolean = true;
				
				if (except != null) {
					
					for (var j:int = 0; j < except.length; j++) {
						if (except[j] == field) {
							aux = false;
							break;
						}
					}
					
				}
				
				if (aux) {
					if (field is DateField) {
						DateField(field).selectedDate = null;
						DateField(field).text = '';
					} else if (field is TextInput) {
						TextInput(field).text = '';
					} else if (field is NumericStepper) {
						NumericStepper(field).value = 0;
					} else if (field is TextArea) {
						TextArea(field).text = '';
					} else if (field is ComboBase) {
						ComboBase(field).selectedIndex = 0;
					} else if (field is ListBase) {
						ListBase(field).selectedIndex = -1;
					} else if (field is CheckBox) {
						CheckBox(field).selected = false;
					}  
					
				}
				
			}
			
		}
		
		public static function selectsFields(fields:Array, values:Array, campo:String = 'codigo') : void {
			
			if (fields == null || values == null
				|| fields.length != values.length) {
				return;
			}
			
			for (var i:int = 0; i < fields.length; i++) {
				selectField(fields[i], values[i], campo);
			}
		}
		
		public static function removeCaracteresEspeciais(...params) : String {
			
			if (params == null || params.length == 0) {
				return null;
			}
			
			var retorno:String;
			
			for (var i:int = 0; i < params.length; i++) {
				
				if (params[i] != null && params[i] is String) {
					
					retorno = params[i].toLowerCase();
					
					for (var j:int = 0; j < acentos.length; j++) {
						retorno = replace(retorno, acentos[j], semAcentos[j]);
					}
					
				}
			}
			return trim(retorno);
		}
		
		public static function replaceAll(str:String, from:String, to:String) : String {
			var idx:int = str.indexOf( from );
			while ( idx > -1 ) {
				str = replace(str, from, to ); 
				idx = str.indexOf( from );
			}
			return trim(str);
		}
		
		public static function replace(str:String, oldSubStr:String, newSubStr:String) : String {
			return str.split(oldSubStr).join(newSubStr);
		}
		
		public static function trim(str:String):String {
			if (str == null) {
				return str;
			}
			return StringUtil.trim(str);
		}
		
		public static function isEmpty(str:Object):Boolean {
			
			if (str == null) {
				return true;
			}
			
			if (str is Number) {
				
				return isNaN(Number(str));
				
			} else {
				
				if (StringUtil.trim(str.toString()).length == 0) {
					return true;
				}
				
			}
			 
			return false;
		}
		
		public static function exportToExcel(_url:String, _params:Object = null) : URLRequest {
			
			var _loaderRequest:URLRequest = new URLRequest(_url);
			
			var tempVars:URLVariables = new URLVariables();			
			
			if (_params != null) {
				for (var keyParam:String in _params) {
					tempVars[keyParam] = _params[keyParam];
				}	
			}

			_loaderRequest.data = tempVars;
			_loaderRequest.method = URLRequestMethod.POST;
			
			return _loaderRequest;
			
		}
		
		public static function validateIntervalDate(dateFieldDe:DateField, dateFieldAte:DateField, nomeCampo:String = null) : String {
			
			if (isEmpty(dateFieldDe.text) && isEmpty(dateFieldAte.text))
			{
				return null;
			}
			
			if (!isEmpty(dateFieldDe.text) && isEmpty(dateFieldAte.text))
			{
				return 'Obrigatório preenchimento da data final '+ (nomeCampo == null ? 'data' : nomeCampo) + '!';
			}
			
			if (isEmpty(dateFieldDe.text) && !isEmpty(dateFieldAte.text))
			{
				return 'Obrigatório preenchimento da data inicio '+ (nomeCampo == null ? 'data' : nomeCampo) + '!';
			}
			
			var dataDe:Date = dateFieldDe.selectedDate == null ? DateField.stringToDate(dateFieldDe.text, 'DD/MM/YYYY') : dateFieldDe.selectedDate;
			
			var dataAte:Date = dateFieldAte.selectedDate == null ? DateField.stringToDate(dateFieldAte.text, 'DD/MM/YYYY') : dateFieldAte.selectedDate;
			
			if (dataDe > dataAte) {
				return 'A data inicio de '+ (nomeCampo == null ? 'data' : nomeCampo) + ' não pode ser superior a final!';
			}
			
			return null;
			
		}
		
		static public function existsInArrayExcept(field:Object, except:Array) : Boolean
		{
			if (!isNullOrEmpty(except)) 
			{
				for (var j:int = 0; j < except.length; j++) 
				{
					if (except[j].toString() == field.toString()) 
					{
						return true;
					}
				}
			}
			
			return false;
			
		}
		
		static public function existsInArrayExceptExcludeNumbers(field:Object, except:Array) : Boolean
		{
			if (!isNullOrEmpty(except)) 
			{
				
				var wordExcept:String = field.toString().replace(/.\d/g, '');
				
				for (var j:int = 0; j < except.length; j++) 
				{
					if (except[j].toString() == wordExcept) 
					{
						return true;
					}
				}
			}
			
			return false;
			
		}
		
		static public function decodeValue(value:String, decode:Boolean = true) : String
		{
			if (decode)
			{
				return decodeURIComponent(value).replace(/\+/g, " ");	
			}
			else
			{
				return value;
			}
		}
		
		static public function concatArrayToStringStartIndex(array:Array, index:int) : String
		{
			
			var value:String = '';
			
			for (var i:int = index; i < array.length; i++)
			{
				value += array[i].toString();
				
				if ((i + 1) < array.length)
				{
					value += '.';
				}
			}
			
			return value;
			
		}
		
		static public function convertImageToByteArray(img:IBitmapDrawable, width:int = 114, height:int = 114, quality:int = 75) : ByteArray
		{
			
			var bmd:BitmapData = new BitmapData(width, height, true);    
			
			bmd.draw(img);     
			
			var jpgEncoder:JPEGEncoder = new JPEGEncoder(quality);
			
			return jpgEncoder.encode(bmd);
			
		}
		
		static public function isNumeric(p_string:String):Boolean
		{
			if (p_string == null)
			{
				return false;
			}
			
			var regx:RegExp=/^[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?$/;
			
			return regx.test(p_string);
			
		}  
		
		static public function isNull(object:Object) : Boolean
		{
			return object == null;	
		}
		
		static public function isNullOrEmpty(object:Object) : Boolean
		{
			
			if (isNull(object)) 
			{
				return true;
			}
			
			if (object is Number) 
			{
				return isNaN(Number(object));
			} 
			else if (object is ArrayCollection) 
			{
				return (ArrayCollection(object).length == 0);
			}
			else if (object is Array) 
			{
				var array:Array = object as Array;
				return (array.length == 0);
			} 
			else 
			{
				if (SMStringUtils.trim(object.toString()).length == 0) 
				{
					return true;
				}
			}
			
			return false;
			
		}
		
		static public function selectedItems(source:Array, nomeCampo:String = 'codigo') : Array 
		{
			if (source != null) 
			{ 
				var temp:Array = new Array();
				
				for (var j:int = 0; j < source.length; j++) 
				{
					temp.push(DRMUtils.findValueForObjectByFieldName(source[j], nomeCampo));
				}
				
				return temp;
				
			}  
			
			return null;
			
		}
		
		static public function contains(source:Array, item:Object, nomeCampo:String = 'codigo') : Boolean 
		{ 
			if (source != null) 
			{ 
				
				var valueObject:Object = DRMUtils.findValueForObjectByFieldName(item, nomeCampo);
				
				if (valueObject == null) 
				{
					return false;
				}
				
				for each (var _item:Object in source) 
				{ 
					
					var valueObjectAux:Object = DRMUtils.findValueForObjectByFieldName(_item, nomeCampo);
					
					if (valueObjectAux == valueObject) 
					{ 
						return true; 
					} 
					
				} 
				
			}
			
			return false;
			
		} 
		
		static public function removeItem(source:Array, item:Object, nomeCampo:String = 'codigo') : void 
		{ 
			
			if (source != null) 
			{ 
				
				var valueObject:Object = DRMUtils.findValueForObjectByFieldName(item, nomeCampo);
				
				if (valueObject == null) 
				{
					return;
				}
				
				for (var i:int = 0; i < source.length; i++) 
				{
					
					var valueObjectAux:Object = DRMUtils.findValueForObjectByFieldName(source[i], nomeCampo);
					
					if (valueObjectAux == valueObject) 
					{ 
						source.removeItemAt(i);
						break;
					}
				}
			} 
		} 
		
		static public function removeItens(source:Array, itens:Array, nomeCampo:String = 'codigo') : void 
		{ 
			if (source != null) 
			{ 
				for (var i:int = 0; i < itens.length; i++) 
				{
					
					var valueObject:Object = DRMUtils.findValueForObjectByFieldName(itens[i], nomeCampo);
					
					if (valueObject == null) 
					{
						continue;
					}
					
					for (var j:int = 0; j < source.length; j++) 
					{
						var valueObjectAux:Object = DRMUtils.findValueForObjectByFieldName(source[j], nomeCampo);
						
						if (valueObject == valueObjectAux) 
						{ 
							source.removeItemAt(j);
							break;
						}
					}					
				}
			} 
		}
		
		static public function selectComboBox(combo:ComboBox, value:Object, campo:String = 'codigo') : void 
		{
			
			if (isNullOrEmpty(value)) 
			{
				return;
			}
			
			for (var i:int = 0; i < combo.dataProvider.length; i++) 
			{
				
				var valueObject:Object = DRMUtils.findValueForObjectByFieldName(combo.dataProvider[i], campo);
				
				if (valueObject == value) 
				{
					combo.selectedIndex = i;				
					break;
				}
			}
			
			//Force dispatch event para resolver o problema do syncronizar com dependencia.
			combo.dispatchEvent(new Event(Event.CHANGE));
			
		} 
		
		static public function selectList(list:ListBase, value:Object, campo:String = 'codigo') : void {
			
			if (isNullOrEmpty(value)) 
			{
				return;
			}
			
			if (value is ArrayCollection) 
			{
				selectListArrayCollection(list, ArrayCollection(value), campo);
			}
			else if (value is Array) 
			{
				selectListArrayCollection(list, new ArrayCollection(value as Array), campo);
			} 
			
		}
		
		static private function selectListArrayCollection(list:ListBase, collection:ArrayCollection, campo:String = 'codigo') : void 
		{
			
			var indices:Array = new Array();		
			
			for (var j:int = 0; j < collection.length; j++) 
			{
				
				var valueObject:Object = DRMUtils.findValueForObjectByFieldName(collection[j], campo);
				
				if (isNull(valueObject)) 
				{
					continue;
				}
				
				for (var i:int = 0; i < list.dataProvider.length; i++) 
				{
					
					var valueObjectAux:Object = DRMUtils.findValueForObjectByFieldName(list.dataProvider[i], campo);
					
					if (valueObject == valueObjectAux)  
					{
						indices.push(i);							
						break;
					}
				}
			}
			
			list.selectedIndices = indices;
			
		} 
		
		static public function addContainerPopUpWindowCenter(container:Container) : void
		{
			
			var parent:Sprite = new Sprite();
			
			var sm:ISystemManager = FlexGlobals.topLevelApplication.systemManager as ISystemManager;
			
			var mp:Object = sm.getImplementation("mx.managers.IMarshallPlanSystemManager");
			
			if (mp && mp.useSWFBridge())
			{
				parent = Sprite(sm.getSandboxRoot());
			}					
			else
			{
				parent = Sprite(FlexGlobals.topLevelApplication);
			}	
			
			PopUpManager.addPopUp(container, parent, true);
			
		}
		
		static public function calculatePercent(fator:Number, total:Number) : Number
		{
			return Math.round((fator * 100) / total);
		}
		
		
	}
}